package com.oro.validator.hibernate;

import java.io.Serializable;
import java.util.regex.Matcher;

import org.hibernate.validator.Validator;


public class CodiceFiscaleValidator implements Validator<CodiceFiscale>,
		Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7801188922088242867L;
	private java.util.regex.Pattern pattern;
	private String regex = "^[A-Za-z]{6}[0-9]{2}[A-Za-z][0-9]{2}[A-Za-z][0-9]{3}[A-Za-z]$";
	private int dispari[] = { 1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18, 20,
			11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23 };

	@Override
	public void initialize(CodiceFiscale parameters) {
		pattern = java.util.regex.Pattern.compile(regex);
	}

	@Override
	public boolean isValid(Object value) {
		if (value == null) {
			return true;
		}
		if (!(value instanceof String)) {
			return false;
		}

		String string = (String) value;
		if (string.length() == 0) {
			return true;
		}

		Matcher m = pattern.matcher(string);

		if (!m.matches()) {
			return false;
		}

		String cf = string.toUpperCase();

		int i = 0, s = 0, c = 0;

		for (i = 1; i <= 13; i += 2) {
			c = cf.charAt(i);
			if (c >= '0' && c <= '9') {
				s = s + c - '0';
			} else {
				s = s + c - 'A';
			}
		}
		for (i = 0; i <= 14; i += 2) {
			c = cf.charAt(i);
			if (c >= '0' && c <= '9') {
				c = c - '0' + 'A';
			}
			s = s + dispari[c - 'A'];
		}

		return s % 26 + 'A' == cf.charAt(15);
	}
}
